use std::{sync::Arc};

use chrono::{Local};
use prisma_client_rust::QueryError;
use serde::{Serialize, Deserialize};
use uuid::Uuid;

use crate::prisma::{PrismaClient, opinion_programme_book, config, meeting, record, action_record, opinion};
use rspc::Type;
use tuple_utils::Append;

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct  OpinionPayload {
    pub uuid: String,
    pub slug: String,
    pub description: String,
    pub content: String,
    pub remark: String,
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct ProgrameBookPayload {
    pub uuid: String,
    pub node: String,
    pub next: String,
    pub node_id: String,
    pub state: String,
    pub status: String,
    pub book_node: String,
    pub book_next: String,
    pub book_node_id: String,
    pub book_state: String,
    pub book_status: String,
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct  ImportPayloadSchema {
    pub uuid: String,
    pub node: String,
    pub next: String,
    pub node_id: String,
    pub state: String,
    pub status: String,
    pub note: String,
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct MeetingPayload {
    pub uuid: Option<String>,
    pub slug: String,
    pub started_at: String,
    pub time: String,
    pub presenter: String,
    pub types: String,
    pub members: String,
    pub outline: Option<String>,
    pub attachment: Option<String>,
    pub status: String
}


#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct ConfigPayload {
    key: String,
    value: String
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct RecordPayload {
    uuid: String,
    relation_uuid: String,
    module: String,
    content: String,
    approval_at: String,
    sended_at: String
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct ImportPayload {
    pub opinion: Option<Vec<OpinionPayload>>,
    pub meeting: Option<Vec<ImportPayloadSchema>>,
    pub programme: Option<Vec<ImportPayloadSchema>>,
    pub book: Option<Vec<ImportPayloadSchema>>,
    pub config: Option<Vec<ConfigPayload>>,
    pub record: Option<Vec<RecordPayload>>,
    pub action: Option<ActionPayload>
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct UuidOfState {
    uuid: String,
    state: String
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct ActionPayload {
    name: String,
    module: String,
    types: String
}

#[derive(Clone, Serialize, Deserialize, Debug, Type)]
pub struct ExportPayload {
    pub programme: Option<Vec<UuidOfState>>,
    pub book: Option<Vec<UuidOfState>>,
    pub report: Option<String>,
    pub rectification: Option<String>,
    pub meeting: Option<Vec<UuidOfState>>,
    pub record: Option<Vec<RecordPayload>>,
    pub action: Option<ActionPayload>
}

pub struct  HandleManager {}

impl HandleManager {

    // 执行导入时事务逻辑
    pub async fn import(client: Arc<PrismaClient>, args: ImportPayload) -> Result<(), QueryError> {
        println!("{:?}", args);


        let _ = client
            ._transaction()
            .run(|client| async move {
                let result = ();

                 // 反馈意见
                if !args.opinion.is_none() {
                    let opinions = args.opinion.unwrap().clone();

                    for item in opinions {
                        let _result = client
                            .opinion()
                            .upsert(
                                opinion::uuid::equals(item.uuid.to_string()),
                                (
                                    item.uuid.clone().to_string(),
                                    item.slug.clone().to_string(),
                                    vec![
                                        opinion::content::set(Some(item.content.clone().to_string())),
                                        opinion::created_at::set(Local::now().into()),
                                        opinion::description::set(Some(item.description.clone().to_string())),
                                        opinion::remark::set(Some(item.remark.clone().to_string()))
                                    ]
                                ),
                                vec![
                                    opinion::slug::set(item.slug.clone().to_string()),
                                    opinion::content::set(Some(item.content.clone().to_string())),
                                    opinion::updated_at::set(Some(Local::now().into())),
                                    opinion::description::set(Some(item.description.clone().to_string())),
                                    opinion::remark::set(Some(item.remark.clone().to_string()))
                                ]
                            )
                            .exec()
                            .await?;

                        result.append(_result);
                    }
                }


                if !args.programme.is_none() {
                    let programmes = args.programme.unwrap().clone();

                    for item in programmes {
                        let exist = client
                            .opinion_programme_book()
                            .find_first(vec![
                                opinion_programme_book::uuid::equals(item.uuid.clone().to_string()),
                            ])
                            .exec()
                            .await?;
                        if !exist.is_none() {
                            let _result = client
                                .opinion_programme_book()
                                .update(
                                    opinion_programme_book::uuid::equals(item.uuid.to_string()),
                                    vec![
                                        opinion_programme_book::state::set(Some(item.state.clone().to_string())),
                                        opinion_programme_book::node::set(Some(item.node.clone().to_string())),
                                        opinion_programme_book::node_id::set(Some(item.node_id.clone().to_string())),
                                        opinion_programme_book::next::set(Some(item.next.clone().to_string())),
                                        opinion_programme_book::status::set(Some("".to_string())),
                                        opinion_programme_book::note::set(Some(item.note.clone().to_string()))
                                    ]
                                )
                                .exec()
                                .await?;

                            result.append(_result);
                        }
                    }
                }

                if !args.book.is_none() {
                    let books = args.book.unwrap().clone();

                    for item in books {
                        let exist = client
                            .opinion_programme_book()
                            .find_first(vec![
                                opinion_programme_book::uuid::equals(item.uuid.clone().to_string()),
                            ])
                            .exec()
                            .await?;

                        if !exist.is_none() {
                            let _result = client
                                .opinion_programme_book()
                                .update(
                                    opinion_programme_book::uuid::equals(item.uuid.to_string()),
                                    vec![
                                        opinion_programme_book::book_state::set(Some(item.state.clone().to_string())),
                                        opinion_programme_book::book_node::set(Some(item.node.clone().to_string())),
                                        opinion_programme_book::book_node_id::set(Some(item.node_id.clone().to_string())),
                                        opinion_programme_book::book_next::set(Some(item.next.clone().to_string())),
                                        opinion_programme_book::book_status::set(Some("".to_string())),
                                        opinion_programme_book::book_note::set(Some(item.note.clone().to_string()))
                                    ]
                                )
                                .exec()
                                .await?;

                            result.append(_result);
                        }
                    }
                }

                // 整改会议
                if !args.meeting.is_none() {
                    let meetings = args.meeting.unwrap().clone();

                    for item in meetings {
                        let exist = client
                            .meeting()
                            .find_first(vec![
                                meeting::uuid::equals(item.uuid.clone().to_string()),
                            ])
                            .exec()
                            .await?;
                        if !exist.is_none() {
                            let _result = client
                                .meeting()
                                .update(
                                    meeting::uuid::equals(item.uuid.clone().to_string()),
                                    vec![
                                        meeting::state::set(Some(item.state.clone().to_string())),
                                        meeting::node::set(Some(item.node.clone().to_string())),
                                        meeting::node_id::set(Some(item.node_id.clone().to_string())),
                                        meeting::next::set(Some(item.next.clone().to_string())),
                                        meeting::status::set(Some("".to_string())),
                                        meeting::note::set(Some(item.note.clone().to_string()))
                                    ],
                                )
                                .exec()
                                .await?;

                            result.append(_result);
                        }
                    }
                }

                // 配置
                if !args.config.is_none() {
                    let configs = args.config.unwrap().clone();

                    for item in configs {
                        let _result = client
                            .config()
                            .upsert(
                                config::key::equals(item.key.clone().to_string()),
                                // uuid, key, value
                                (
                                    Uuid::new_v4().clone().to_string(),
                                    item.key.to_string(),
                                    item.value.to_string(),
                                    vec![]
                                ),
                                vec![
                                    config::key::set(item.key.to_string()),
                                    config::value::set(item.value.to_string()),
                                    config::updated_at::set(Some(Local::now().into()))
                                ]
                            )
                            .exec()
                            .await?;

                        result.append(_result);
                    }
                }

                // 审批记录
                if !args.record.is_none() {
                    let records = args.record.unwrap().clone();

                    for item in records {
                        let _result = client
                            .record()
                            .upsert(
                                record::uuid::equals(item.uuid.to_string()),
                                // uuid, relation_uuid, content, module
                                (
                                    item.uuid.to_string(),
                                    item.relation_uuid.to_string(),
                                    item.content.to_string(),
                                    item.module.to_string(),
                                    Local::now().timestamp_millis().to_string(),
                                    vec![
                                        record::approval_at::set(Some(item.approval_at.to_string())),
                                        record::sended_at::set(Some(item.sended_at.to_string()))
                                    ]
                                ),
                                vec![
                                    record::relation_uuid::set(item.relation_uuid.to_string()),
                                    record::content::set(item.content.to_string()),
                                    record::module::set(item.module.to_string()),
                                    record::approval_at::set(Some(item.approval_at.to_string())),
                                    record::sended_at::set(Some(item.sended_at.to_string()))
                                ]
                            )
                            .exec()
                            .await?;

                        result.append(_result);
                    }
                }

                if !args.action.is_none() {
                    let action = client
                        .action_record()
                        .create(
                            String::from("1"),
                            args.action.clone().unwrap().name,
                            args.action.clone().unwrap().module,
                            Local::now().timestamp_millis().to_string(),
                            vec![
                                action_record::types::set(args.action.clone().unwrap().types.into()),
                            ]
                        )
                        .exec()
                        .await?;

                    result.append(action);
                }

                Ok(result) as Result<(), QueryError>
            })
            .await?;

        return Ok(())
    }

    // 执行导出时事务逻辑
    pub async fn export(client: Arc<PrismaClient>, args: ExportPayload) -> Result<(), QueryError> {
        let _ = client
            ._transaction()
            .run(|client| async move {
                let result = ();
                if !args.programme.is_none() {
                    let collect = args.programme
                        .clone()
                        .unwrap();

                    for item in collect {
                        let _result = client
                            .opinion_programme_book()
                            .update(
                                opinion_programme_book::uuid::equals(item.clone().uuid.to_string()),
                                vec![
                                    opinion_programme_book::status::set(Some("".to_string())),
                                    opinion_programme_book::updated_at::set(Some(Local::now().into())),
                                    opinion_programme_book::state::set(Some(item.clone().state.to_string()))
                                ]
                            )
                            .exec()
                            .await?;

                        result.append(_result);
                    }

                    // let _tmp_results = args.programme
                    //     .unwrap()
                    //     .clone()
                    //     .iter()
                    //     .map(|item| async {
                    //         println!("{}", "开始");
                    //         let _result = client
                    //         .opinion_programme_book()
                    //         .update(
                    //             opinion_programme_book::uuid::equals(item.clone().uuid.to_string()),
                    //             vec![
                    //                 opinion_programme_book::status::set(Some("".to_string())),
                    //                 opinion_programme_book::updated_at::set(Some(Local::now().into())),
                    //                 opinion_programme_book::state::set(Some(item.clone().state.to_string()))
                    //             ]
                    //         )
                    //         .exec()
                    //         .await;

                    //         result.append(Arc::new(_result));
                    //     });

                    // tmp_results.clone().into_iter().map(|item| move {
                    //     return item;
                    // })

                    // _.clone().map(|item| {
                    //     result.append(item);
                    // });
                    // let programme = client
                    //     .opinion_programme_book()
                    //     .update_many(
                    //         vec![
                    //             opinion_programme_book::uuid::in_vec(args.programme.unwrap().to_vec())
                    //         ],
                    //         vec![
                    //             opinion_programme_book::status::set(Some("".to_string())),
                    //             opinion_programme_book::updated_at::set(Some(Local::now().into())),
                    //             opinion_programme_book::state::set("")
                    //         ]
                    //     )
                    //     .exec()
                    //     .await?;

                    // result.append(programme);
                }


                if !args.book.is_none() {
                    let collect = args.book
                        .clone()
                        .unwrap();

                    for item in collect {
                        let _result = client
                            .opinion_programme_book()
                            .update(
                                opinion_programme_book::uuid::equals(item.clone().uuid.to_string()),
                                vec![
                                    opinion_programme_book::book_status::set(Some("".to_string())),
                                    opinion_programme_book::updated_at::set(Some(Local::now().into())),
                                    opinion_programme_book::book_state::set(Some(item.clone().state.to_string()))
                                ]
                            )
                            .exec()
                            .await?;

                        result.append(_result);
                    }
                    // let book = client
                    //     .opinion_programme_book()
                    //     .update_many(
                    //         vec![
                    //             opinion_programme_book::uuid::in_vec(args.book.unwrap().to_vec())
                    //         ],
                    //         vec![
                    //             opinion_programme_book::book_status::set(Some("".to_string())),
                    //             opinion_programme_book::updated_at::set(Some(Local::now().into()))
                    //         ]
                    //     )
                    //     .exec()
                    //     .await?;

                    // result.append(book);
                }

                if !args.report.is_none() {
                    let report = client
                        .config()
                        .update(
                            config::key::equals("report".to_string()),
                            vec![
                                config::value::set(args.report.clone().unwrap().to_string()),
                                config::updated_at::set(Some(Local::now().into()))
                            ]
                        )
                        .exec()
                        .await?;

                    result.append(report);
                }

                if !args.rectification.is_none() {
                    let rectification = client
                        .config()
                        .update(
                            config::key::equals("rectification".to_string()),
                            vec![
                                config::value::set(args.rectification.clone().unwrap().to_string()),
                                config::updated_at::set(Some(Local::now().into()))
                            ]
                        )
                        .exec()
                        .await?;

                    result.append(rectification);
                }

                if !args.meeting.is_none() {
                    let collect = args.meeting
                        .clone()
                        .unwrap();

                    for item in collect {
                        let _result = client
                            .meeting()
                            .update(
                                meeting::uuid::equals(item.clone().uuid.to_string()),
                                vec![
                                    meeting::status::set(Some("".to_string())),
                                    meeting::updated_at::set(Some(Local::now().into())),
                                    meeting::state::set(Some(item.clone().state.to_string()))
                                ]
                            )
                            .exec()
                            .await?;

                        result.append(_result);
                    }
                    // let meeting = client
                    //     .meeting()
                    //     .update_many(
                    //         vec![
                    //             meeting::uuid::in_vec(args.meeting.unwrap().to_vec())
                    //         ],
                    //         vec![
                    //             meeting::status::set(Some("".to_string())),
                    //             meeting::updated_at::set(Some(Local::now().into()))
                    //         ],
                    //     )
                    //     .exec()
                    //     .await?;

                    // result.append(meeting);
                }

                if !args.record.is_none() {
                    let record = client
                        .record()
                        .create_many(
                            args.record
                            .unwrap()
                            .into_iter()
                            .map(|item| {
                                return record::create_unchecked(
                                    item.clone().uuid.to_string(),
                                    item.clone().relation_uuid.to_string(),
                                    item.clone().content.to_string(),
                                    item.clone().module.to_string(),
                                    Local::now().timestamp_millis().to_string(),
                                    vec![
                                        record::approval_at::set(Some(item.clone().approval_at.to_string())),
                                        record::sended_at::set(Some(item.sended_at.to_string()))
                                    ]
                                )
                            })
                            .collect()
                        )
                        .exec()
                        .await?;

                    result.append(record);
                }

                if !args.action.is_none() {
                    let action = client
                        .action_record()
                        .create(
                            String::from("1"),
                            args.action.clone().unwrap().name.to_string(),
                            args.action.clone().unwrap().module.to_string(),
                            Local::now().timestamp_millis().to_string(),
                            vec![
                                action_record::types::set(args.action.clone().unwrap().types.into()),
                            ]
                        )
                        .exec()
                        .await?;

                    result.append(action);
                }

                println!("{:?}", result);
                Ok(result) as Result<(), QueryError>
            })
            .await?;

        return Ok(())
    }
}
